package com.jeesite.modules.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 云闪付工具类
 * @author LaVenderGong
 * @version 2025-08-17
 */
@Component
public class UnionpayUtil {

    private static final Logger logger = LoggerFactory.getLogger(UnionpayUtil.class);

    @Value("${unionpay.merchant.id:}")
    private String merchantId;

    @Value("${unionpay.merchant.key:}")
    private String merchantKey;

    @Value("${unionpay.gateway.url:}")
    private String gatewayUrl;

    @Value("${unionpay.notify.url:}")
    private String notifyUrl;

    @Value("${unionpay.return.url:}")
    private String returnUrl;

    /**
     * 检查云闪付配置是否完整
     */
    public boolean checkConfig() {
        boolean isValid = merchantId != null && !merchantId.trim().isEmpty() &&
                         merchantKey != null && !merchantKey.trim().isEmpty() &&
                         gatewayUrl != null && !gatewayUrl.trim().isEmpty();
        
        if (!isValid) {
            logger.warn("云闪付配置不完整: merchantId={}, merchantKey={}, gatewayUrl={}", 
                merchantId != null ? "已配置" : "未配置",
                merchantKey != null ? "已配置" : "未配置", 
                gatewayUrl != null ? "已配置" : "未配置");
        }
        
        return isValid;
    }

    /**
     * 创建云闪付支付订单
     */
    public Map<String, Object> createPayment(String orderId, String amount, String subject) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            if (!checkConfig()) {
                result.put("success", false);
                result.put("message", "云闪付配置不完整");
                return result;
            }

            // 构建支付参数
            Map<String, String> params = new HashMap<>();
            params.put("version", "5.1.0");
            params.put("encoding", "UTF-8");
            params.put("signMethod", "01");
            params.put("txnType", "01");
            params.put("txnSubType", "01");
            params.put("bizType", "000201");
            params.put("channelType", "07");
            params.put("accessType", "0");
            params.put("merId", merchantId);
            params.put("orderId", orderId);
            params.put("txnTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
            params.put("txnAmt", convertYuanToCent(amount));
            params.put("currencyCode", "156");
            params.put("orderDesc", subject);
            params.put("backUrl", notifyUrl);
            params.put("frontUrl", returnUrl);

            // 生成签名
            String signature = generateSignature(params);
            params.put("signature", signature);

            // 构建支付表单HTML
            String formHtml = buildPaymentForm(params);

            result.put("success", true);
            result.put("paymentType", "form");
            result.put("formHtml", formHtml);
            result.put("orderId", orderId);
            result.put("message", "云闪付订单创建成功");

            logger.info("云闪付订单创建成功，订单号: {}, 金额: {}", orderId, amount);

        } catch (Exception e) {
            logger.error("创建云闪付订单失败，订单号: " + orderId, e);
            result.put("success", false);
            result.put("message", "创建云闪付订单失败: " + e.getMessage());
        }

        return result;
    }

    /**
     * 验证云闪付回调签名
     */
    public boolean verifyCallback(Map<String, String> params) {
        try {
            if (!checkConfig()) {
                return false;
            }

            String receivedSignature = params.get("signature");
            if (receivedSignature == null || receivedSignature.trim().isEmpty()) {
                logger.warn("云闪付回调缺少签名");
                return false;
            }

            // 移除签名参数
            Map<String, String> verifyParams = new HashMap<>(params);
            verifyParams.remove("signature");

            // 生成验证签名
            String calculatedSignature = generateSignature(verifyParams);

            boolean isValid = receivedSignature.equals(calculatedSignature);
            if (!isValid) {
                logger.warn("云闪付回调签名验证失败，接收到的签名: {}, 计算的签名: {}", 
                    receivedSignature, calculatedSignature);
            }

            return isValid;

        } catch (Exception e) {
            logger.error("验证云闪付回调签名异常", e);
            return false;
        }
    }

    /**
     * 查询云闪付订单状态
     */
    public Map<String, Object> queryOrderStatus(String orderId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            if (!checkConfig()) {
                result.put("success", false);
                result.put("message", "云闪付配置不完整");
                return result;
            }

            // 构建查询参数
            Map<String, String> params = new HashMap<>();
            params.put("version", "5.1.0");
            params.put("encoding", "UTF-8");
            params.put("signMethod", "01");
            params.put("txnType", "00");
            params.put("txnSubType", "00");
            params.put("bizType", "000000");
            params.put("accessType", "0");
            params.put("merId", merchantId);
            params.put("orderId", orderId);
            params.put("txnTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));

            // 生成签名
            String signature = generateSignature(params);
            params.put("signature", signature);

            // 这里应该调用云闪付查询接口，目前返回模拟数据
            result.put("success", true);
            result.put("orderId", orderId);
            result.put("status", "PROCESSING");
            result.put("message", "查询成功");

            logger.info("查询云闪付订单状态，订单号: {}", orderId);

        } catch (Exception e) {
            logger.error("查询云闪付订单状态失败，订单号: " + orderId, e);
            result.put("success", false);
            result.put("message", "查询失败: " + e.getMessage());
        }

        return result;
    }

    /**
     * 将元转换为分
     */
    private String convertYuanToCent(String yuan) {
        try {
            BigDecimal yuanAmount = new BigDecimal(yuan);
            BigDecimal centAmount = yuanAmount.multiply(new BigDecimal("100"));
            return centAmount.setScale(0, BigDecimal.ROUND_HALF_UP).toString();
        } catch (Exception e) {
            logger.error("金额转换失败: " + yuan, e);
            return "0";
        }
    }

    /**
     * 生成签名
     */
    private String generateSignature(Map<String, String> params) {
        try {
            // 按参数名排序
            TreeMap<String, String> sortedParams = new TreeMap<>(params);
            
            // 构建签名字符串
            StringBuilder signStr = new StringBuilder();
            for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
                if (entry.getValue() != null && !entry.getValue().trim().isEmpty()) {
                    if (signStr.length() > 0) {
                        signStr.append("&");
                    }
                    signStr.append(entry.getKey()).append("=").append(entry.getValue());
                }
            }
            
            // 添加密钥
            signStr.append("&").append(merchantKey);
            
            // SHA-256加密
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] digest = md.digest(signStr.toString().getBytes("UTF-8"));
            
            // 转换为十六进制字符串
            StringBuilder hexStr = new StringBuilder();
            for (byte b : digest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexStr.append('0');
                }
                hexStr.append(hex);
            }
            
            return hexStr.toString().toUpperCase();
            
        } catch (Exception e) {
            logger.error("生成云闪付签名失败", e);
            return "";
        }
    }

    /**
     * 构建支付表单HTML
     */
    private String buildPaymentForm(Map<String, String> params) {
        StringBuilder formHtml = new StringBuilder();
        formHtml.append("<html><head><meta charset='UTF-8'></head><body>");
        formHtml.append("<form id='unionpayForm' method='post' action='").append(gatewayUrl).append("'>");
        
        for (Map.Entry<String, String> entry : params.entrySet()) {
            formHtml.append("<input type='hidden' name='").append(entry.getKey())
                   .append("' value='").append(entry.getValue()).append("'/>");
        }
        
        formHtml.append("<input type='submit' value='立即支付' style='display:none;'/>");
        formHtml.append("</form>");
        formHtml.append("<script>document.getElementById('unionpayForm').submit();</script>");
        formHtml.append("</body></html>");
        
        return formHtml.toString();
    }
}
